热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

首部|门限_计算机网络测试人关于TCP的学习和梳理

篇首语:本文由编程笔记#小编为大家整理,主要介绍了计算机网络测试人关于TCP的学习和梳理相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了计算机网络测试人关于TCP的学习和梳理相关的知识,希望对你有一定的参考价值。




通过阅读《计算机网络–自顶向下方法》,以及结合最近面试的一些经历,作此笔记进行梳理和总结,也为日后的回顾作基底。



文章目录


  • 1)什么是TCP?
    • 1.1 TCP与运输层
      • *面试常问之TCP和HTTP的联系和区别

    • 1.2 TCP与UDP
      • 无连接运输:UDP
      • 面向连接的运输:TCP
      • UDP与TCP的区别:


  • 2)面试常问之TCP如何实现可靠传输?
    • 2.1 连接管理
      • 连接建立过程(三次握手):
        • *面试常问之为什么是三次握手而不是两次?

      • 连接关闭过程(四次挥手):
        • *面试常问之为什么是四次挥手而不是三次?
        • *面试常问之2MSL:


    • 2.2 校验和
    • 2.3 序列号和ACK信号
    • 2.4 超时重传
    • 2.5 滑动窗口
    • 2.6 流量控制
    • 2.7 拥塞控制





1)什么是TCP?

1.1 TCP与运输层



运输层(Transport Layer)位于应用层和网络层之间,该层协议为运行在不同主机上的应用进程之间提供了逻辑通信功能。


  • 即应用进程使用运输层提供的逻辑通信功能彼此发送报文,而无须考虑承载这些报文的物理基础设施的细节。
  • 运输层和网络层的关系:运输层位于网络层之上,网络层提供主机之间的逻辑通信服务,运输层为运行在不同主机上的进程之间提供逻辑通信服务。
  • 关于网络层级架构具体介绍可移步《【计算机网络】OSI与TCP/IP网络架构》。

运输层协议在端系统中实现:


  • 在发送端:将来自发送应用进程的应用报文分块,每块加上一个运输层首部以生成运输层报文段(segment),然后传递给网络层。
  • 在接收端:处理接收到的报文段,将其中的数据供接收应用进程使用。


*面试常问之TCP和HTTP的联系和区别


联系:


  • HTTP协议的数据一般是基于TCP协议进行传输的。
    • 关于HTTP的详细介绍可移步《【计算机网络】测试人关于HTTP的学习和梳理》。

区别:


  • HTTP属于应用层协议,定义了传输数据内容的规范。

  • TCP属于运输层协议,定义了数据传输和连接方式的规范。

  • HTTP算是短连接,TCP算是长连接。


因特网有两种协议(TCP和UDP),可为调用的应用程序提供一组不同的传输层服务。


  • UDP(用户数据报协):为调用它的应用程序提供了一种不可靠的、无连接的服务。
  • TCP(传输控制协议):为调用它的应用程序提供了一种可靠的、面向连接的服务。

TCP和UDP最基本的责任是将两个端系统间IP的交付服务扩展成运行在端系统上的两个进程之间的交付服务,即运输层的多路复用和多路分解:


  • 多路分解:将运输层报文段中的数据交付到正确的套接字。
  • 多路复用:从不同套接字中收集数据块、为其封装首部信息以生成报文段、将报文段传递给网络层。
    • 要求:套接字有唯一标识符(源端口号字段)、报文段有特殊字段指示目的套接字(目的端口号字段)。
      • 端口号(0 - 65535)
      • 周知端口号(0 - 1023),在[RFC1700]给出,在[RFC3232]更新。


网络层协议(IP,网际协议)为主机之间提供逻辑通信,其服务模型是尽力而为交付服务(best-effort delivery
service)。


  • 因为其不确保报文段的交付,不保证报文段的按序交付,不保证报文段中的数据的完整性,因此也被称为不可靠服务(unreliable service)




1.2 TCP与UDP


  • 无连接运输:UDP


    • 工作原理:给从应用进程得到的数据添加源和目的端口号字段,以及两个其他的小字段(长度和校验和),然后交给网络层,反之则将IP报文段的数据根据目的端口号交付给正确的应用进程。
    • 适用场景:
      • 实时应用(通常要求最小的发送速率,不过分延迟,可容忍部分数据丢失)
      • 特定服务(无连接因此可支持更多的活跃客户,以及更快)
      • 如DNS、SNMP、网络电话、实时视频会议、流式存储音频与视频

  • 面向连接的运输:TCP


    • 工作原理:
      • 面向连接:通过三次握手建立连接,四次挥手断开连接。
      • 通过差错检测、重传、累积确认、定时器、序号和确认号来保证可靠传输。
      • TCP定义在RFC793、RFC1122、RFC1323、RFC2018、RFC2581中。
    • 常用场景:如SMTP、Telnet等。

  • UDP与TCP的区别:


    • 无连接与有连接
    • TCP要求系统资源较多,UDP较少
    • UDP程序结构较简单
    • TCP保证数据正确性,UDP可能丢包
    • TCP保证数据顺序,UDP不保证
    • 详细的区别可参考:https://blog.csdn.net/Li_Ning_/article/details/52117463





2)面试常问之TCP如何实现可靠传输?

TCP服务模型是一个字节流,TCP必须检测并修补所有在IP层(及下面的层)产生的数据传输问题,如丢包、重复以及错误。



2.1 连接管理

一个TCP连接通常分为3个阶段:启动、数据传输、退出(关闭)。



  • 一个TCP连接由一对端点或套接字构成,通信的每一端都由一对(IP地址、端口号)所唯一标识。


  • 连接建立过程(三次握手):

    三次握手的目的不仅在于让通信双方了解一个连接正在建立,而且还利用SYN报文段交换彼此的初始序列号(ISN)。

    1. 客户端发送一个SYN报文段,并指明自己想要连接的端口号和初始序列号x(表明传送数据时的第一个数据字节的序号是 x)。
    2. 服务器发送响应SYN报文段,包含其初始序列号y,此外确认号ack=x+1(若出现丢失的情况,该SYN段会被重传)。
    3. 客户端为了确认服务器的SYN,发送确认号ack=y+1的报文。


*面试常问之为什么是三次握手而不是两次?


为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。


  • 详细原因:如果在发送过程中的话,假如是两次:
    • 当A给B发送一个连接请求,因为网络的原因该请求没有按时到达,A就会重新发送一次请求,这次请求正常到,然后B就会给A一个确认请求,此时就可以传送数据了。
    • 但是当A第一次发送的数据又来到了(A以为这个包已经丢失了),那么B就会再次向A发送一个确认,此时的A就不知道这个确认的意义了,而B就会在一直等待着A给他发送信息(如果这样的次数很多就会导致资源浪费)。
    • 所以不能是两次。




  • 连接关闭过程(四次挥手):

    通过发送一个FIN报文段来发起关闭操作,由于TCP的通信模型是双向的,所以只有连接双方都完成关闭操作后,才构成一个完整关闭。

    1. 连接的主动关闭者发送一个FIN段,进入FIN_WAIT_1。
    2. 被动关闭者发送的报文段中确认号ack=u+1,以表明其已经成功收到主动关闭者的FIN。此时,上层应用程序会被告知连接的另一端已经提出了关闭的请求。
    3. 若此时没有要发送的数据时,应用程序会发起自己的关闭操作,接着被动关闭者的身份转变为主动关闭者,并发送自己的FIN。
    4. 收到连接释放报文段后,为了完成连接的关闭,还会发送一个ACK用于确认上一个FIN。注意,当出现FIN丢失的情况,发送方会重新传输直到收到一个ACK确认。


*面试常问之为什么是四次挥手而不是三次?


因为TCP连接是全双工的,也就是说接收到FIN只是说没有数据再发过来,但是还是可以向对方发送数据的,也就是说接受到一个FIN只是关闭了一个方向的数据传输,另一个方向还可以继续发送数据


  • 前两次挥手只是确认关闭了一个方向的数据,加上后面两次挥手才真正的关闭了整个全双工连接。

  • 当socket在ESTABISHED状态时,它想主动关闭连接于是向对方发送FIN请求,发送完FIN请求后它处于FIN_WAIT_1状态,当对方确认ACK报文后则处于FIN_WAIT_2状态。


    • FIN_WAIT_2表示半连接,也就是有一方要求关闭连接,另一方收到请求但是告诉它我还有一些数据要发送稍后会关闭。
    • TIME_WAIT状态表示收到对方的FIN并发送出ACK


如果是三次挥手,则可能在关闭后还有一个方向没有关




*面试常问之2MSL:


客户端接收到服务器端的 FIN 报文后进入TIME_WAIT状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:


  • 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
  • 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文




2.2 校验和

发送的数据包的二进制相加然后取反,目的是检测数据在传输过程中的任何变化。


  • 如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。

2.3 序列号和ACK信号

发送方按照顺序给要发送的数据包的每个字节都标上编号。
接收方接收到发送方的数据包之后,回传一个ACK信号,标识下一个需求的数据包初始字节编号。


  • 序列号:
    • TCP提供一个字节流接口,把一个应用程序的字节流转换为一组IP可以携带的分组,这些分组包含序列号。
    • 序列号在TCP中实际代表了每个分组的第一个字节在整个数据流中的字节偏移。
    • 通过序列号的使用,一个TCP接收端可丢弃重复的报文段和记录以乱序到达的报文段。

  • ACK信号:
    • 当TCP接收到另一端的数据时,会发送一个确认。
    • TCP使用的ACK是累积的,一个指示字节号N的ACK表示了所有直到N的字节(但不包括N)已经成功被接收了。



2.4 超时重传



发送方没有接收到响应的ACK报文原因可能有两点:


  • 数据在传输过程中由于网络原因等直接全体丢包,接收方没有接收到。
  • 接收方接收到了响应的数据,但是发送的ACK报文响应却由于网络原因丢包了。


TCP在解决这个问题的时候引入了一个新的机制,叫做超时重传机制。


发送方在发送完数据后等待一个时间,该时间内没有接收到ACK报文,那么就会重新发送刚才的数据。


  • 如果是上述第一个原因,则接收方收到二次重发的数据后,便进行ACK应答。
  • 如果是第二个原因,接收方发现接收的数据已存在(判断存在的根据就是序列号,所以说序列号还有去除重复数据的作用),那么直接丢弃,仍旧发送ACK应答。
  • 等待时间的设定:
    • 为了保证在任何环境下都有一个高性能的通信,因此这个最大超时时间(也就是等待的时间)是动态计算的。
      • 超时以500ms(0.5秒)为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。
      • 重发一次后,仍未响应,那么等待2500ms的时间后,再次重传。等待4500ms的时间继续重传。以一个指数的形式增长。
    • 累计到一定的重传次数,TCP就认为网络或者对端出现异常,强制关闭连接。



2.5 滑动窗口



TCP必需要解决的可靠传输以及包乱序(reordering)的问题,所以,TCP必需要知道网络实际的数据处理带宽或是数据处理速度,这样才不会引起网络拥塞,导致丢包。


  • 发送方滑动窗口示意图:

    分成了四个部分,分别是(其中那个黑模型就是滑动窗口):


    1. 已收到ack确认的数据。
    2. 已发出但还没收到ack的。
    3. 在窗口中还没有发出的(接收方还有空间)。
    4. 窗口以外的数据(接收方没空间)。

  • 下面是个滑动后的示意图(收到36的ack,并发出了46-51的字节):


滑动窗口中窗口前段为已发送但为收到ACK的数据,后段为待发送数据。


  • 发送端一次发送多个数据,接收端回传收到的连续数据的ACK信号,缓存缺失数据之后的数据包(保持顺序)。
  • 当发送端收到ACK信号时,窗口向前依次移动,直到遇到有数据未确认时停止。
  • 一段时间后启动超时重传,接收端若收到缺失数据,则和缓存数据一起发送ACK信号,否则,抛弃缓存数据。



2.6 流量控制



接收端在接收到数据后,对其进行处理。


  • 如果发送端的发送速度太快,导致接收端的结束缓冲区很快的填充满了。此时如果发送端仍旧发送数据,那么接下来发送的数据都会丢包,继而导致丢包的一系列连锁反应,如超时重传。


而TCP根据接收端对数据的处理能力,决定发送端的发送速度,这个机制就是流量控制。


简单来说就是接收方处理不过来的时候,就把窗口缩小,并把窗口值告诉发送端。


  • TCP首部有一个字段来通知窗口的大小,接收端通过设置来主动控制传输流量。
  • 如果接收到窗口大小的值为0,那么发送方将停止发送数据,并定期的向接收端发送窗口探测数据段,让接收端把窗口大小告诉发送端。



2.7 拥塞控制



  • 如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。
    • 这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度
  • 发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口

发送端通过拥塞窗口主动控制传输流量。主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。


  • 慢开始:防止双方通信刚开始就传送大量数据包,发送端拥塞窗口初始设置为1MSS(以报文段而非字节为单位),每接受一个ACK信号,窗口扩大为两倍。


    • 发送数据时,取拥塞窗口和滑动窗口的较小值。同时设定一个慢启动阈值,初始值设置为16个报文段,即ssthresh=16。

  • 拥塞避免:


    • 一开始以慢开始算法(指数增长)。当cwnd=16时开始执行拥塞避免算法,呈现线性增长。
    • 当拥塞窗口cwnd=24时出现超时,发送方判定为网络拥塞,于是调整门限值ssthresh=cwnd/2=12,同时设置拥塞窗口为1,进入慢开始阶段。
    • 按照慢开始算法,发送方每收到一个新报文段的确认ACK拥塞窗口值增加。当cwnd=12时(图中点3)执行拥塞避免算法。


TCP以段为单位发送数据包:在建立TCP连接的同时,两端协商发送数据包的单位,称为“最大消息长度”:MSS。


  • 【TCP数据(MSS字节)】【TCP首部(20字节)】【IP首部(20字节)】


  • 快重传和快恢复:
    • 当cwnd=16时(图中点4)出现了一个新的情况,就是发送方连续收到3个对统一报文段的重复确认(3-ACK)。发送方执行快重传和快恢复算法。
      • 在图中点4,发送方知道只是丢失了个别的报文段,于是不启动慢开始,而是先进行快重传然后执行快恢复算法。
      • 发送方设置调整门限值ssthresh=cwnd/2=8, 同时拥塞窗口cwnd=ssthresh=8(点5),然后进行拥塞避免算法。
    • 快重传:收到3个同样的确认就立刻重传特定的报文,不等到超时。
    • 快恢复:cwnd不是从1重新开始。




【部分内容参考自】


  • 《计算机网络–自顶向下方法》
  • 《TCP/IP详解 卷1:协议》
  • TCP的三次握手和四次挥手:https://www.cnblogs.com/xiaokang01/p/10032377.html
  • TCP实现可靠传输:https://www.cnblogs.com/walker993/p/9570902.html
  • TCP协议如何保证可靠传输:https://www.cnblogs.com/xiaokang01/p/10033267.html

推荐阅读
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 众筹商城与传统商城的区别及php众筹网站的程序源码
    本文介绍了众筹商城与传统商城的区别,包括所售产品和玩法不同以及运营方式不同。同时还提到了php众筹网站的程序源码和方维众筹的安装和环境问题。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
author-avatar
yun建2502930453
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有